package route

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
)

// 添加中间件
func (m *Mux) addTransform(Func func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		log.Printf("[%s]%s=>%s\n", r.Method, r.RemoteAddr, r.URL.String())
		// 跨域处理
		if m.cors {
			w.Header().Set("Access-Control-Allow-Origin", "*")
			w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
			w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
			if r.Method == "OPTIONS" {
				w.WriteHeader(http.StatusOK)
				return
			}
		}
		// 验证鉴权
		if m.authFunc(&w, r) {
			log.Println("验证成功，允许请求")
			Func(w, r)
		} else {
			w.Header().Add("Content-Type", "application/json; charset=utf-8")
			w.WriteHeader(401)
			log.Println("验证失败，拒绝请求")
			fmt.Fprint(w, `{"error":"未经授权的访问"}`)
		}
	}
}

// 静态文件服务
func (m *Mux) AddFileDir(pattern string, dir string, memo string) {
	os.MkdirAll(dir, 0777)
	if !strings.HasPrefix(pattern, "/") {
		pattern = "/" + pattern
	}
	if !strings.HasSuffix(pattern, "/") {
		pattern = pattern + "/"
	}
	m.AddRoute(&Route{
		Pattern: pattern,
		Memo:    fmt.Sprintf("目录[%s]的静态文件服务：%s", dir, memo),
		Func:    http.StripPrefix(pattern, http.FileServer(http.Dir(dir))).ServeHTTP,
	})
}

func (m *Mux) AddRoute(route *Route) {
	if memo := m.pool[route.Pattern]; memo != "" {
		log.Panicf("Mux-AddRoute操作失败\n路由冲突%s\n原功能：%s\n冲突功能：%s", route.Pattern, memo, route.Memo)
	}
	m.pool[route.Pattern] = route.Memo
	m.mux.HandleFunc(route.Pattern, m.addTransform(route.Func))
}

func (m *Mux) AddRouteGroup(group *RouteGroup) {
	if memo := m.groups[group.Pattern]; memo != "" {
		log.Panicf("Mux-AddRouteGroup操作失败\n路由冲突%s\n原功能：%s\n冲突功能：%s", group.Pattern, memo, group.Memo)
	}
	// 绑定mux，后续group可继续添加Route
	group.mux = m
	m.groups[group.Pattern] = group.Memo
	for _, v := range group.Array {
		m.AddRoute(v)
	}
}

func (m *Mux) AddIRouteGroup(group IRouteGroup) {
	m.AddRouteGroup(group.RouteGroup())
}

func (m *Mux) AddIRoute(route IRoute) {
	m.AddRoute(route.Route())
}

func (m *Mux) CreateRouteGroup(pattern string, memo string) *RouteGroup {
	group := NewRouteGroup(pattern, memo, m)
	m.AddRouteGroup(group)
	return group
}
